﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using InformationExtraction.Common;
using InformationExtraction.Interface;
using System.Text.RegularExpressions;
using System.IO;

namespace InformationExtraction.Utils
{
    //ww
    class AcronymExtracter : IFeatureExtractable
    {
        private int lastCurrentLineNum = -1;

        private bool isLineSat = false;


        #region IFeatureExtractable 成员

        List<int> IFeatureExtractable.Extract(Token token)
        {
            List<int> result = new List<int>();


            if (token.InLine != null)
            {

                if (token.InLine.No != lastCurrentLineNum)
                {
                    lastCurrentLineNum = token.InLine.No;
                    isLineSat = HasSpecialWordsInLines(token.InLine.RawContent);

                    if (token.InLine.PriorLine != null)
                    {
                        isLineSat = isLineSat || HasSpecialWordsInLines(token.InLine.PriorLine.RawContent);
                    }

                    if (token.InLine.NextLine != null)
                    {
                        isLineSat = isLineSat || HasSpecialWordsInLines(token.InLine.NextLine.RawContent);
                    }
                }
            }



            result.Add(AcronymFeature_1(token));
            result.Add(AcronymFeature_2(token));
            result.Add(AcronymFeature_3(token));
            result.Add(AcronymFeature_4(token));
            result.Add(AcronymFeature_5(token));
            result.Add(AcronymFeature_6(token));
            result.Add(AcronymFeature_7(token));
            result.Add(AcronymFeature_8(token));
            result.Add(AcronymFeature_9(token));

            return result;
        }

        InformationType IFeatureExtractable.GetTargetType()
        {
            return InformationType.Acronym;
        }

        #endregion


        #region Extract Features
        /// <summary>
        /// 用-或者&apos;隔开，前面是大写字母，后面是数字
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private int AcronymFeature_1(Token token)
        {
            int index1 = token.Content.IndexOf("&apos;");
            int index2 = token.Content.IndexOf("-");

            if (index1 > 0)
            {
                string[] seps = token.Content.Split(new string[] { "&apos;" }, StringSplitOptions.RemoveEmptyEntries);

                if (seps.Length == 2)
                {
                    if (IsAllCaptial(seps[0].Trim()) && IsAllDigits(seps[1].Trim()) && !IsDate(seps[0].Trim()))
                    {
                        return 1;
                    }
                }
                else if (seps.Length == 1)
                {
                    if (IsAllCaptial(seps[0].Trim()) || IsAllCaptial(seps[0].Trim()) && !IsDate(seps[0].Trim()))
                        return 1;
                }
            }

            if (index2 > 0)
            {
                string[] seps = token.Content.Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries);

                if (seps.Length == 2)
                {
                    if (IsAllCaptial(seps[0].Trim()) && IsAllDigits(seps[1].Trim()) && !IsDate(seps[0].Trim()))
                    {
                        return 1;
                    }
                }
            }

            return -1;
        }

        /// <summary>
        /// 所有字母大写，且下一个单词是&apos;数字
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private int AcronymFeature_2(Token token)
        {
            string content = token.Content;
            if (IsAllCaptial(content) && !IsDate(content))
            {
                if (token.Next != null)
                {
                    string nextcontent = token.Next.Content;
                    if (nextcontent.StartsWith("&apos;"))
                    {
                        nextcontent = nextcontent.Replace("&apos;", "");
                        if (IsAllDigits(nextcontent))
                        {
                            return 1;
                        }
                    }
                }
            }

            return -1;
        }


        /// <summary>
        /// 所有字母大写+&apos;，且下一个单词是数字
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private int AcronymFeature_3(Token token)
        {
            string content = token.Content; //.Replace("&apos;", "");

            if (content.EndsWith("&apos;"))
            {
                content = token.Content.Replace("&apos;", "");
                if (IsAllCaptial(content) && !IsDate(content.Trim()))
                {
                    if (token.Next != null)
                    {
                        string nextcontent = token.Next.Content;

                        if (IsAllDigits(nextcontent))
                        {
                            return 1;
                        }

                    }
                }
            }

            return -1;
        }


        /// <summary>
        /// 所有字母大写，且下一个单词是数字
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private int AcronymFeature_4(Token token)
        {
            string content = token.Content;
            if (IsAllCaptial(content) && !IsDate(content.Trim()))
            {
                if (token.Next != null)
                {
                    string nextcontent = token.Next.Content;
                    if (IsAllDigits(nextcontent))
                    {
                        return 1;
                    }
                }
            }

            return -1;
        }

        /// <summary>
        /// 均为数字，且上一个单词是大写字母&apos;
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private int AcronymFeature_5(Token token)
        {
            string content = token.Content;
            if (IsAllDigits(content))
            {
                if (token.Prior != null)
                {
                    string precontent = token.Prior.Content;
                    if (precontent.EndsWith("&apos;"))
                    {
                        precontent = precontent.Replace("&apos;", "");
                        if (IsAllCaptial(precontent) && !IsDate(precontent.Trim()))
                        {
                            return 1;
                        }
                    }
                }
            }

            return -1;
        }




        /// <summary>
        /// 均为&apos数字，且上一个单词是大写字母
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private int AcronymFeature_6(Token token)
        {
            string content = token.Content;
            if (content.StartsWith("&apos;"))
            {
                content = token.Content.Replace("&apos;", "");
                if (IsAllDigits(content))
                {
                    if (token.Prior != null)
                    {
                        string precontent = token.Prior.Content;
                        if (IsAllCaptial(precontent) && !IsDate(precontent.Trim()))
                        {
                            return 1;
                        }
                    }
                }
            }

            return -1;
        }


        /// <summary>
        /// 均为数字，且上一个单词是大写字母
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private int AcronymFeature_7(Token token)
        {
            string content = token.Content;

            if (IsAllDigits(content))
            {
                if (token.Prior != null)
                {
                    string precontent = token.Prior.Content;
                    if (IsAllCaptial(precontent) && !IsDate(precontent.Trim()))
                    {
                        return 1;
                    }
                }
            }

            return -1;
        }


        /// <summary>
        /// 大写字母加数字
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        private int AcronymFeature_8(Token token)
        {
            bool flag = false;

            int index = 0;

            for (int i = 0; i < token.Content.Length; i++)
            {
                if (!Char.IsUpper(token.Content[i]))
                {
                    index = i;
                    break;
                }
            }

            //前index个是大写字母
            if (index > 0 && !IsDate(token.Content.Substring(0, index).Trim()))
            {
                flag = true;

                for (int i = index; i < token.Content.Length; i++)
                {
                    if (!Char.IsDigit(token.Content[i]))
                    {
                        flag = false;
                        break;
                    }
                }
            }

            if (flag)
                return 1;
            else return -1;

        }

        private int AcronymFeature_9(Token token)
        {
            if (isLineSat)
                return 1;
            else
                return -1;
        }


        #endregion




        #region Util Function
        private bool IsAllCaptial(string s)
        {
            bool flag = true;
            for (int i = 0; i < s.Length; i++)
            {
                if (!Char.IsUpper(s[i]) && s[i] != '-' && s[i] != '/')
                {
                    flag = false;
                    break;
                }
            }
            return flag;
        }


        private bool IsAllDigits(string s)
        {
            bool flag = true;
            for (int i = 0; i < s.Length; i++)
            {
                if (!Char.IsDigit(s[i]))
                {
                    flag = false;
                    break;
                }
            }
            return flag;
        }

        private bool IsDate(string s)
        {
            Regex r = new Regex("(.*)(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEPT|OCT|NOV|DEC|MON|TUES|THUR|WED|FRI|SAT|SUN)(.*)");
            Match m = r.Match(s);

            if (m.Success)
            {
                return true;
            }

            return false;
        }

        private bool HasSpecialWordsInLines(string content)
        {
            Regex r = new Regex("(.*)(Conference|conference|CONFERENCE|conferences|workshops|Workshop|workshop|held in|held|" +
 "symposium|Symposium|SYMPOSIUM|meeting)(.*)", RegexOptions.IgnoreCase);
            Match m = r.Match(content);

            if (m.Success)
            {
                return true;
            }

            return false;
        }
        #endregion


        private void OutputTemp(Token token)
        {
            using (StreamWriter sw = new StreamWriter("acronym_see_f1.txt", true, Encoding.UTF8))
            {
                sw.WriteLine(token.Content);
            }
        }


        private void doSomething(Token token)
        {
            using (StreamWriter sw = new StreamWriter("acronym_line.txt", true, Encoding.UTF8))
            {
                if (token.Type == InformationType.Acronym)
                {
                    double accountfor = token.InLine.No * 1.0 / token.InLine.InDocument.LineCount * 1.0;
                    sw.WriteLine(accountfor);
                }
            }


            using (StreamWriter sw = new StreamWriter("acronym_currline.txt", true, Encoding.UTF8))
            {
                if (token.Type == InformationType.Acronym)
                {
                    if (token.InLine != null && token.InLine.RawContent != null)
                        sw.WriteLine(token.InLine.RawContent);
                }
            }

            using (StreamWriter sw = new StreamWriter("acronym_preline.txt", true, Encoding.UTF8))
            {
                if (token.Type == InformationType.Acronym)
                {
                    if (token.InLine != null && token.InLine.PriorLine != null && token.InLine.PriorLine.RawContent != null)
                        sw.WriteLine(token.InLine.PriorLine.RawContent);
                }
            }

            using (StreamWriter sw = new StreamWriter("acronym_nextline.txt", true, Encoding.UTF8))
            {
                if (token.Type == InformationType.Acronym)
                {
                    if (token.InLine != null && token.InLine.NextLine != null && token.InLine.NextLine.RawContent != null)
                        sw.WriteLine(token.InLine.NextLine.RawContent);
                }
            }


        }
    }
}
